﻿Imports System.Collections.ObjectModel

<Serializable()>
Public Class JoinInfo
    Implements ICriteriaContainer

    Public Sub New()
        mCriteria = New CriteriaGroup(True)
    End Sub
    Public Sub New(Table As String)
        Me.New()
        Me.Table = Table
    End Sub
    Sub New(Table As String, LeftExpression As String, CriteriaOp As Operation, RightExpression As String)
        Me.new(Table)
        AddCriteria(LeftExpression, CriteriaOp, RightExpression)
    End Sub

    Public Property Table As String
    Public Property JoinType As JoinType
    Private mCriteria As CriteriaGroup

    Public Sub AddCriteria(ByVal Criteria As ICriteriaComponent) Implements ICriteriaContainer.AddCriteria
        AddCriteria(Criteria, BooleanOperator.[Default])
    End Sub
    Public Sub AddCriteria(ByVal Criteria As IEnumerable(Of ICriteriaComponent)) Implements ICriteriaContainer.AddCriteria
        For Each Crit As ICriteriaComponent In Criteria
            AddCriteria(Crit, BooleanOperator.[Default])
        Next
    End Sub
    Public Sub AddCriteria(ByVal Criteria As ICriteriaComponent, ByVal Op As BooleanOperator) Implements ICriteriaContainer.AddCriteria
        mCriteria.AddCriteria(Criteria, Op)
    End Sub
    Public Function AddCriteria(LeftExpression As String, CriteriaOp As Operation, RightExpression As String) As Criteria Implements ICriteriaContainer.AddCriteria
        Return AddCriteria(LeftExpression, CriteriaOp, RightExpression, BooleanOperator.[Default])
    End Function
    Public Function AddCriteria(LeftExpression As String, CriteriaOp As Operation, RightExpression As String, Op As BooleanOperator) As Criteria Implements ICriteriaContainer.AddCriteria
        Return mCriteria.AddCriteria(LeftExpression, CriteriaOp, RightExpression, Op, ExpressionType.Logical)
    End Function

    Public ReadOnly Property CriteriaCount As Integer Implements ICriteriaContainer.CriteriaCount
        Get
            Return mCriteria.CriteriaCount
        End Get
    End Property

    Public Property RenderParens As Boolean Implements ICriteriaContainer.RenderParens
        Get
            Return False
        End Get
        Set(value As Boolean)
            'Ignore set value
        End Set
    End Property


    Public Function GetText() As String
        Return GetText(QueryOptions.DefaultOptions)
    End Function
    Public Function GetText(options As QueryOptions) As String
        Return GetJoinTypeText() & " JOIN " & Table & " ON " & mCriteria.GetText(options)
    End Function

    Private Function GetJoinTypeText() As String
        Select Case JoinType
            Case QBuilder.JoinType.Cross
                Return "CROSS"
            Case QBuilder.JoinType.FullOutter
                Return "OUTTER"
            Case QBuilder.JoinType.Inner
                Return "INNER"
            Case QBuilder.JoinType.LeftOutter
                Return "LEFT"
            Case QBuilder.JoinType.RightOutter
                Return "RIGHT"
            Case Else
                Throw New InvalidOperationException("Invalid Join Type")
        End Select
    End Function

    Public Function Criteria() As System.Collections.Generic.IEnumerable(Of ICriteriaComponent) Implements ICriteriaContainer.Criteria
        Return mCriteria.Criteria
    End Function

    Public Sub ClearCriteria() Implements ICriteriaContainer.ClearCriteria
        mCriteria.ClearCriteria()
    End Sub
End Class

Public Enum JoinType As Integer
    Inner = 0
    LeftOutter
    RightOutter
    FullOutter
    Cross
End Enum